class Game2048 {
    constructor() {
        this.grid = [];
        this.score = 0;
        this.bestScore = parseInt(localStorage.getItem('bestScore')) || 0;
        this.size = 4;
        this.won = false;
        this.over = false;
        
        this.initializeGame();
        this.setupEventListeners();
        this.updateDisplay();
    }
    
    initializeGame() {
        this.grid = Array(this.size).fill().map(() => Array(this.size).fill(0));
        this.score = 0;
        this.won = false;
        this.over = false;
        
        this.addRandomTile();
        this.addRandomTile();
        this.updateDisplay();
    }
    
    setupEventListeners() {
        document.addEventListener('keydown', (e) => {
            if (this.over && !this.won) return;
            
            const keyMap = {
                'ArrowUp': () => this.move('up'),
                'ArrowDown': () => this.move('down'),
                'ArrowLeft': () => this.move('left'),
                'ArrowRight': () => this.move('right')
            };
            
            if (keyMap[e.key]) {
                e.preventDefault();
                keyMap[e.key]();
            }
        });
        
        document.getElementById('restart-btn').addEventListener('click', () => {
            this.initializeGame();
            this.hideGameMessage();
        });
        
        document.getElementById('try-again-btn').addEventListener('click', () => {
            this.initializeGame();
            this.hideGameMessage();
        });
        
        // Touch events for mobile
        let startX, startY;
        const container = document.querySelector('.game-container');
        
        container.addEventListener('touchstart', (e) => {
            startX = e.touches[0].clientX;
            startY = e.touches[0].clientY;
        });
        
        container.addEventListener('touchend', (e) => {
            if (!startX || !startY) return;
            
            const endX = e.changedTouches[0].clientX;
            const endY = e.changedTouches[0].clientY;
            
            const deltaX = endX - startX;
            const deltaY = endY - startY;
            
            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                if (deltaX > 30) this.move('right');
                else if (deltaX < -30) this.move('left');
            } else {
                if (deltaY > 30) this.move('down');
                else if (deltaY < -30) this.move('up');
            }
            
            startX = null;
            startY = null;
        });
        
        // Handle screen resize
        window.addEventListener('resize', () => {
            this.updateDisplay();
        });
    }
    
    addRandomTile() {
        const emptyCells = [];
        
        for (let i = 0; i < this.size; i++) {
            for (let j = 0; j < this.size; j++) {
                if (this.grid[i][j] === 0) {
                    emptyCells.push({ row: i, col: j });
                }
            }
        }
        
        if (emptyCells.length > 0) {
            const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
            this.grid[randomCell.row][randomCell.col] = Math.random() < 0.9 ? 2 : 4;
        }
    }
    
    move(direction) {
        const previousGrid = this.grid.map(row => [...row]);
        let moved = false;
        
        switch (direction) {
            case 'left':
                moved = this.moveLeft();
                break;
            case 'right':
                moved = this.moveRight();
                break;
            case 'up':
                moved = this.moveUp();
                break;
            case 'down':
                moved = this.moveDown();
                break;
        }
        
        if (moved) {
            this.addRandomTile();
            this.updateDisplay();
            
            if (this.checkWin()) {
                this.showGameMessage('恭喜！你达到了 2048！', 'game-won');
                this.won = true;
            } else if (this.checkGameOver()) {
                this.showGameMessage('游戏结束！', 'game-over');
                this.over = true;
            }
        }
    }
    
    moveLeft() {
        let moved = false;
        
        for (let i = 0; i < this.size; i++) {
            const row = this.grid[i].filter(val => val !== 0);
            
            for (let j = 0; j < row.length - 1; j++) {
                if (row[j] === row[j + 1]) {
                    row[j] *= 2;
                    this.score += row[j];
                    row.splice(j + 1, 1);
                }
            }
            
            while (row.length < this.size) {
                row.push(0);
            }
            
            if (JSON.stringify(row) !== JSON.stringify(this.grid[i])) {
                moved = true;
            }
            
            this.grid[i] = row;
        }
        
        return moved;
    }
    
    moveRight() {
        let moved = false;
        
        for (let i = 0; i < this.size; i++) {
            const row = this.grid[i].filter(val => val !== 0);
            
            for (let j = row.length - 1; j > 0; j--) {
                if (row[j] === row[j - 1]) {
                    row[j] *= 2;
                    this.score += row[j];
                    row.splice(j - 1, 1);
                    j--;
                }
            }
            
            while (row.length < this.size) {
                row.unshift(0);
            }
            
            if (JSON.stringify(row) !== JSON.stringify(this.grid[i])) {
                moved = true;
            }
            
            this.grid[i] = row;
        }
        
        return moved;
    }
    
    moveUp() {
        let moved = false;
        
        for (let j = 0; j < this.size; j++) {
            const column = [];
            for (let i = 0; i < this.size; i++) {
                if (this.grid[i][j] !== 0) {
                    column.push(this.grid[i][j]);
                }
            }
            
            for (let i = 0; i < column.length - 1; i++) {
                if (column[i] === column[i + 1]) {
                    column[i] *= 2;
                    this.score += column[i];
                    column.splice(i + 1, 1);
                }
            }
            
            while (column.length < this.size) {
                column.push(0);
            }
            
            for (let i = 0; i < this.size; i++) {
                if (this.grid[i][j] !== column[i]) {
                    moved = true;
                }
                this.grid[i][j] = column[i];
            }
        }
        
        return moved;
    }
    
    moveDown() {
        let moved = false;
        
        for (let j = 0; j < this.size; j++) {
            const column = [];
            for (let i = 0; i < this.size; i++) {
                if (this.grid[i][j] !== 0) {
                    column.push(this.grid[i][j]);
                }
            }
            
            for (let i = column.length - 1; i > 0; i--) {
                if (column[i] === column[i - 1]) {
                    column[i] *= 2;
                    this.score += column[i];
                    column.splice(i - 1, 1);
                    i--;
                }
            }
            
            while (column.length < this.size) {
                column.unshift(0);
            }
            
            for (let i = 0; i < this.size; i++) {
                if (this.grid[i][j] !== column[i]) {
                    moved = true;
                }
                this.grid[i][j] = column[i];
            }
        }
        
        return moved;
    }
    
    checkWin() {
        for (let i = 0; i < this.size; i++) {
            for (let j = 0; j < this.size; j++) {
                if (this.grid[i][j] === 2048) {
                    return true;
                }
            }
        }
        return false;
    }
    
    checkGameOver() {
        for (let i = 0; i < this.size; i++) {
            for (let j = 0; j < this.size; j++) {
                if (this.grid[i][j] === 0) {
                    return false;
                }
                
                if (j < this.size - 1 && this.grid[i][j] === this.grid[i][j + 1]) {
                    return false;
                }
                
                if (i < this.size - 1 && this.grid[i][j] === this.grid[i + 1][j]) {
                    return false;
                }
            }
        }
        return true;
    }
    
    updateDisplay() {
        const tileContainer = document.getElementById('tile-container');
        tileContainer.innerHTML = '';
        
        // Check if mobile view
        const isMobile = window.innerWidth <= 520;
        const tileSize = isMobile ? 55 : 75;
        const gap = 10;
        
        for (let i = 0; i < this.size; i++) {
            for (let j = 0; j < this.size; j++) {
                if (this.grid[i][j] !== 0) {
                    const tile = document.createElement('div');
                    tile.className = `tile tile-${this.grid[i][j]}`;
                    tile.textContent = this.grid[i][j];
                    tile.style.left = `${j * (tileSize + gap)}px`;
                    tile.style.top = `${i * (tileSize + gap)}px`;
                    
                    tileContainer.appendChild(tile);
                }
            }
        }
        
        document.getElementById('score').textContent = this.score;
        
        if (this.score > this.bestScore) {
            this.bestScore = this.score;
            localStorage.setItem('bestScore', this.bestScore);
        }
        
        document.getElementById('best-score').textContent = this.bestScore;
    }
    
    showGameMessage(message, className) {
        const messageElement = document.getElementById('game-message');
        messageElement.querySelector('p').textContent = message;
        messageElement.className = `game-message ${className}`;
        messageElement.style.display = 'block';
    }
    
    hideGameMessage() {
        const messageElement = document.getElementById('game-message');
        messageElement.style.display = 'none';
        messageElement.className = 'game-message';
    }
}

// Initialize the game when page loads
document.addEventListener('DOMContentLoaded', () => {
    new Game2048();
});